from django.contrib.auth.models import AbstractUser
from django.contrib.auth.password_validation import ValidationError
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.conf import settings
import uuid
from lib.utils import is_chinese

class InviteCode(models.Model):
    """
    Invitation code for user registration
    """
    code = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        editable=False,
        verbose_name=_("邀请码")
    )
    max_uses = models.PositiveIntegerField(
        # NOTE we here use 0 to indicate infinity uses since number input field
        blank=False,
        default=0,
        verbose_name=_("最大使用次数"),
        help_text=_("0代表无限")
    )
    times_used = models.PositiveIntegerField(
        default=0,
        verbose_name=_("已使用次数"),
        blank=False
    )
    creater = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=False,
        verbose_name=_("创建者"),
        related_name='generated_codes'
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name=_("创建时间")
    )

    class Meta:
        db_table = "invite_code"
        default_permissions = []
        verbose_name = _('邀请码')
        verbose_name_plural = verbose_name

    def clean(self):
        super().clean()
        if self.max_uses and self.times_used > self.max_uses:
            raise ValidationError(
                _("time_used is greater than max_uses!")
            )
        
    def __str__(self):
        return f"{self.code} ({self.times_used}/{self.max_uses or '∞'})"


# Name should be 'User', cannot change due to Historical Issue
# Django database is very hard to change  AUTH_USER_MODEL in settings.py in the middle of a
# project.
class UserProfile(AbstractUser):
    """
    Custom User Model
    """
    # TODO for fields like telephone, use specific verification.
    
    class ThirdApp(models.IntegerChoices):
        LOCAL_USER = 0, _("本地用户")
        # KJY_PASSPORT = 1, _('科技云通行证')
        AAI = 2, _("身份认证联盟AAI")

    telephone = models.CharField(
        verbose_name=_("电话"), max_length=11, blank=True, default=""
    )
    company = models.CharField(
        verbose_name=_("公司/单位"), max_length=255, blank=True, default=""
    )
    third_app = models.SmallIntegerField(
        verbose_name=_("第三方应用登录"),
        choices=ThirdApp.choices,
        default=ThirdApp.LOCAL_USER.value,
    )

    is_researcher = models.BooleanField(
        verbose_name=_("是否是研究者"),
        default=False
    )

    bio = models.TextField(
        verbose_name=_("自我介绍"),
        default="",
        blank=True,
    )
    
    note = models.TextField(
        verbose_name=_("备注"),
        blank=True,
        default="",
    )

    audit_management = GenericRelation(
        'audit.AuditManagement',
        content_type_field='content_type',
        object_id_field='object_id',
    )

    invite_code = models.ForeignKey(
        InviteCode,
        on_delete=models.SET_NULL,
        null=True,
        verbose_name=_("邀请码"),
        related_name='registered_users'
    )

    @property
    def full_name(self):
        return self.get_full_name()

    # override get_full_name function to make it suitable for Chinese name
    def get_full_name(self):
        if is_chinese(self.last_name):
            return f"{self.last_name}{self.first_name}"
        else:
            return f"{self.first_name} {self.last_name}"
    
    def make_researcher(self):
        """Convert user to researcher"""
        if not self.is_researcher:
            self.is_researcher = True
            self.save()
            Researcher.objects.get_or_create(user=self)

    def remove_researcher(self):
        """Remove researcher status"""
        if self.is_researcher:
            self.is_researcher = False
            self.save()
            Researcher.objects.filter(user=self).delete()

    class Meta:
        default_permissions = []
        db_table = 'user_profile'
        verbose_name = _('用户')
        verbose_name_plural = verbose_name
        permissions = [
            ("internal_staff_basic", _("内部员工的基本权限（不同于外部用户）")),
            ("can_manage_projects", _("可以管理项目")),
            # can_manage_user is not able to manage user from admin_site since
            # in admin_site can manage user means can do anything (change role etc.)
            ("can_manage_users", _("可以管理用户")),
            ("can_manage_resources", _("可以管理资源"))
        ]


    # used as default label of the form generated by ManyToManyField
    def __str__(self):
        name = self.full_name
        if not name.strip():
            name = self.username
        else:
            name = f"{name}({self.username})"
        return name

class Researcher(models.Model):
    """
    Extended profile for users who are researchers
    """
    user = models.OneToOneField(
        UserProfile,
        on_delete=models.CASCADE,
        related_name='researcher_profile'
    )
    
    resumes = GenericRelation(
        'media.File',
        content_type_field='object_content_type',
        object_id_field='object_id',
    )

    class Meta:
        db_table = "researcher"
        default_permissions = []
        verbose_name = _('研究者')
        verbose_name_plural = verbose_name



